﻿//ITrader.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.BusinessEntities
{
	using System;
	using System.Collections.Generic;

	using Ecng.Serialization;

	using StockSharp.Logging;

	/// <summary>
	/// Основной интерфейс, предоставляющий шлюз взаимодействия с торговыми системами.
	/// </summary>
	public interface ITrader : IPersistable, ILogReceiver
	{
		/// <summary>
		/// Текстовое описание шлюза.
		/// </summary>
		string DisplayName { get; }

		/// <summary>
		/// Событие появления собственных новых сделок.
		/// </summary>
		event Action<IEnumerable<MyTrade>> NewMyTrades;

		/// <summary>
		/// Событие появления всех новых сделок.
		/// </summary>
		event Action<IEnumerable<Trade>> NewTrades;

		/// <summary>
		/// Событие появления новых заявок.
		/// </summary>
		event Action<IEnumerable<Order>> NewOrders;

		/// <summary>
		/// Событие изменения состояния заявок (снята, удовлетворена).
		/// </summary>
		event Action<IEnumerable<Order>> OrdersChanged;

		/// <summary>
		/// Событие об ошибках, связанных с регистрацией заявок.
		/// </summary>
		event Action<IEnumerable<OrderFail>> OrdersRegisterFailed;

		/// <summary>
		/// Событие об ошибках, связанных со снятием заявок.
		/// </summary>
		event Action<IEnumerable<OrderFail>> OrdersCancelFailed;

		/// <summary>
		/// Событие об ошибках, связанных с регистрацией стоп-заявок.
		/// </summary>
		event Action<IEnumerable<OrderFail>> StopOrdersRegisterFailed;

		/// <summary>
		/// Событие об ошибках, связанных со снятием стоп-заявок.
		/// </summary>
		event Action<IEnumerable<OrderFail>> StopOrdersCancelFailed;

		/// <summary>
		/// Событие появления новых стоп-заявок.
		/// </summary>
		event Action<IEnumerable<Order>> NewStopOrders;

		/// <summary>
		/// Событие изменения состояния стоп-заявок.
		/// </summary>
		event Action<IEnumerable<Order>> StopOrdersChanged;

		/// <summary>
		/// Событие появления новых инструментов.
		/// </summary>
		event Action<IEnumerable<Security>> NewSecurities;

		/// <summary>
		/// Событие изменения параметров инструментов.
		/// </summary>
		event Action<IEnumerable<Security>> SecuritiesChanged;

		/// <summary>
		/// Событие появления новых портфелей.
		/// </summary>
		event Action<IEnumerable<Portfolio>> NewPortfolios;

		/// <summary>
		/// Событие изменения параметров портфелей.
		/// </summary>
		event Action<IEnumerable<Portfolio>> PortfoliosChanged;

		/// <summary>
		/// Событие появления новых позиций.
		/// </summary>
		event Action<IEnumerable<Position>> NewPositions;

		/// <summary>
		/// Событие изменения параметров позиций.
		/// </summary>
		event Action<IEnumerable<Position>> PositionsChanged;

		/// <summary>
		/// Событие появления новых стаканов с котировками.
		/// </summary>
		event Action<IEnumerable<MarketDepth>> NewMarketDepths;

		/// <summary>
		/// Событие изменения стаканов с котировками.
		/// </summary>
		event Action<IEnumerable<MarketDepth>> MarketDepthsChanged;

		/// <summary>
		/// Событие появления новых записей в логе заявок.
		/// </summary>
		event Action<IEnumerable<OrderLogItem>> NewOrderLogItems;

		/// <summary>
		/// Событие успешного подключения.
		/// </summary>
		event Action Connected;

		/// <summary>
		/// Событие успешного отключения.
		/// </summary>
		event Action Disconnected;

		/// <summary>
		/// Событие ошибки подключения (например, соединения было разорвано).
		/// </summary>
		event Action<Exception> ConnectionError;

		/// <summary>
		/// Событие, сигнализирующее об ошибке при получении или обработке новых данных с сервера.
		/// </summary>
		event Action<Exception> ProcessDataError;

		/// <summary>
		/// Событие, сигнализирующее о новых экспортируемых данных.
		/// </summary>
		event Action NewDataExported;

		/// <summary>
		/// Событие, сигнализирующее об изменении текущего времени на биржевых площадках <see cref="ExchangeBoards"/>.
		/// Передается разница во времени, прошедшее с последнего вызова события. Первый раз событие передает значение <see cref="TimeSpan.Zero"/>.
		/// </summary>
		event Action<TimeSpan> MarketTimeChanged;

		/// <summary>
		/// Получить биржевое время.
		/// </summary>
		/// <param name="exchange">Биржа.</param>
		/// <returns>Биржевое время.</returns>
		DateTime GetMarketTime(Exchange exchange);

		/// <summary>
		/// Список всех биржевых площадок, для которых загружены инструменты <see cref="Securities"/>.
		/// </summary>
		IEnumerable<ExchangeBoard> ExchangeBoards { get; }

		/// <summary>
		/// Список всех загруженных инструментов.
		/// Вызывать необходимо после того, как пришло событие <see cref="NewSecurities" />. Иначе будет возвращено постое множество.
		/// </summary>
		IEnumerable<Security> Securities { get; }

		/// <summary>
		/// Получить все заявки.
		/// </summary>
		IEnumerable<Order> Orders { get; }

		/// <summary>
		/// Получить все стоп-заявки.
		/// </summary>
		IEnumerable<Order> StopOrders { get; }

		/// <summary>
		/// Получить все ошибки при регистрации заявок.
		/// </summary>
		IEnumerable<OrderFail> OrderRegisterFails { get; }

		/// <summary>
		/// Получить все ошибки при снятии заявок.
		/// </summary>
		IEnumerable<OrderFail> OrderCancelFails { get; }

		/// <summary>
		/// Получить все сделки.
		/// </summary>
		IEnumerable<Trade> Trades { get; }

		/// <summary>
		/// Получить все собственные сделки.
		/// </summary>
		IEnumerable<MyTrade> MyTrades { get; }

		/// <summary>
		/// Получить все портфели.
		/// </summary>
		IEnumerable<Portfolio> Portfolios { get; }

		/// <summary>
		/// Получить все позиции.
		/// </summary>
		IEnumerable<Position> Positions { get; }

		/// <summary>
		/// Проверить соединение.
		/// </summary>
		bool IsConnected { get; }

		/// <summary>
		/// Запущен ли экспорт. Экспорт запускается через метод <see cref="StartExport"/>.
		/// </summary>
		bool IsExportStarted { get; }

		/// <summary>
		/// Поддерживается ли перерегистрация заявок через метод <see cref="ReRegisterOrder(StockSharp.BusinessEntities.Order,StockSharp.BusinessEntities.Order)"/>
		/// в виде одной транзакции.
		/// </summary>
		bool IsSupportAtomicReRegister { get; }

		/// <summary>
		/// Список всех инструментов, зарегистрированных через <see cref="RegisterSecurity"/>.
		/// </summary>
		IEnumerable<Security> RegisteredSecurities { get; }

		/// <summary>
		/// Список всех инструментов, зарегистрированных через <see cref="RegisterMarketDepth"/>.
		/// </summary>
		IEnumerable<Security> RegisteredMarketDepths { get; }

		/// <summary>
		/// Список всех инструментов, зарегистрированных через <see cref="RegisterTrades"/>.
		/// </summary>
		IEnumerable<Security> RegisteredTrades { get; }

		/// <summary>
		/// Список всех инструментов, зарегистрированных через <see cref="RegisterOrderLog"/>.
		/// </summary>
		IEnumerable<Security> RegisteredOrderLogs { get; }

		/// <summary>
		/// Список всех портфелей, зарегистрированных через <see cref="RegisterPortfolio"/>.
		/// </summary>
		IEnumerable<Portfolio> RegisteredPortfolios { get; }

		/// <summary>
		/// Подключиться к торговой системе.
		/// </summary>
		void Connect();

		/// <summary>
		/// Отключиться от торговой системы.
		/// </summary>
		void Disconnect();

        /// <summary>
		/// Переподключиться к торговой системе.
		/// </summary>
		void Reconnect();

		/// <summary>
		/// Запустить экспорт данных из торговой системы в программу (получение портфелей, инструментов, заявок и т.д.).
		/// </summary>
		void StartExport();

		/// <summary>
		/// Остановить экспорт данных из торговой системы в программу, запущенный через <see cref="StartExport"/>.
		/// </summary>
		void StopExport();

		/// <summary>
		/// Перезапустить экспорт данных из торговой системы через методы <see cref="StopExport"/> и <see cref="StartExport"/>.
		/// </summary>
		void ReStartExport();

		/// <summary>
		/// Получить позицию по портфелю и инструменту.
		/// </summary>
		/// <param name="portfolio">Портфель, по которому нужно найти позицию.</param>
		/// <param name="security">Инструмент, по которому нужно найти позицию.</param>
		/// <param name="depoName">Название депозитария, где находится физически ценная бумага.
		/// По-умолчанию передается пустая строка, что означает суммарную позицию по всем депозитариям.</param>
		/// <returns>Позиция.</returns>
		Position GetPosition(Portfolio portfolio, Security security, string depoName = "");

		/// <summary>
		/// Получить стакан котировок.
		/// </summary>
		/// <param name="security">Инструмент, по которому нужно получить стакан.</param>
		/// <returns>Стакан котировок.</returns>
		MarketDepth GetMarketDepth(Security security);

		/// <summary>
		/// Зарегистрировать заявку на бирже.
		/// </summary>
		/// <param name="order">Заявка, содержащая информацию для регистрации.</param>
		void RegisterOrder(Order order);

		/// <summary>
		/// Перерегистрировать заявку на бирже.
		/// </summary>
		/// <param name="oldOrder">Заявка, которую нужно снять.</param>
		/// <param name="newOrder">Новая заявка, которую нужно зарегистрировать.</param>
		void ReRegisterOrder(Order oldOrder, Order newOrder);

		/// <summary>
		/// Перерегистрировать заявку на бирже.
		/// </summary>
		/// <param name="oldOrder">Заявка, которую нужно снять и на основе нее зарегистрировать новую.</param>
		/// <param name="price">Цена новой заявки.</param>
		/// <param name="volume">Объем новой заявки.</param>
		/// <returns>Новая заявка.</returns>
		Order ReRegisterOrder(Order oldOrder, decimal price, decimal volume);

		/// <summary>
		/// Отменить заявку на бирже.
		/// </summary>
		/// <param name="order">Заявка, которую нужно отменить.</param>
		void CancelOrder(Order order);

		/// <summary>
		/// Отменить группу заявок на бирже по фильтру.
		/// </summary>
		/// <param name="isStopOrder">True, если нужно отменить только стоп-заявки, false - если только обычный и null - если оба типа.</param>
		/// <param name="portfolio">Портфель. Если значение равно null, то портфель не попадает в фильтр снятия заявок.</param>
		/// <param name="direction">Направление заявки. Если значение равно null, то направление не попадает в фильтр снятия заявок.</param>
		/// <param name="classCode">Код класса. Если переданная строка пустая, то код не попадает в фильтр снятия заявок.</param>
		/// <param name="security">Инструмент. Если значение равно null, то инструмент не попадает в фильтр снятия заявок.</param>
		void CancelOrders(bool? isStopOrder = null, Portfolio portfolio = null, OrderDirections? direction = null, string classCode = null, Security security = null);

		/// <summary>
		/// Начать получать котировки (стакан) по инструменту.
		/// Значение котировок можно получить через метод <see cref="GetMarketDepth"/>.
		/// </summary>
		/// <param name="security">Инструмент, по которому необходимо начать получать котировки.</param>
		void RegisterMarketDepth(Security security);

		/// <summary>
		/// Остановить получение котировок по инструменту.
		/// </summary>
		/// <param name="security">Инструмент, по которому необходимо остановить получение котировок.</param>
		void UnRegisterMarketDepth(Security security);

		/// <summary>
		/// Начать получать сделки (тиковые данные) по инструменту. Новые сделки будут приходить через
		/// событие <see cref="NewTrades"/>.
		/// </summary>
		/// <param name="security">Инструмент, по которому необходимо начать получать сделки.</param>
		void RegisterTrades(Security security);

		/// <summary>
		/// Остановить получение сделок (тиковые данные) по инструменту.
		/// </summary>
		/// <param name="security">Инструмент, по которому необходимо остановить получение сделок.</param>
		void UnRegisterTrades(Security security);

		/// <summary>
		/// Начать получать новую информацию (например, <see cref="Security.LastTrade"/> или <see cref="Security.BestBid"/>) по инструменту.
		/// </summary>
		/// <param name="security">Инструмент, по которому необходимо начать получать новую информацию.</param>
		void RegisterSecurity(Security security);

		/// <summary>
		/// Остановить получение новой информации.
		/// </summary>
		/// <param name="security">Инструмент, по которому необходимо остановить получение новой информации.</param>
		void UnRegisterSecurity(Security security);

		/// <summary>
		/// Начать получать лог заявок для инструмента.
		/// </summary>
		/// <param name="security">Инструмент, по которому необходимо начать получать лог заявок.</param>
		void RegisterOrderLog(Security security);

		/// <summary>
		/// Остановить получение лога заявок для инструмента.
		/// </summary>
		/// <param name="security">Инструмент, по которому необходимо остановить получение лога заявок.</param>
		void UnRegisterOrderLog(Security security);

		/// <summary>
		/// Начать получать новую информацию по портфелю.
		/// </summary>
		/// <param name="portfolio">Портфель, по которому необходимо начать получать новую информацию.</param>
		void RegisterPortfolio(Portfolio portfolio);

		/// <summary>
		/// Остановить получение новой информации по портфелю.
		/// </summary>
		/// <param name="portfolio">Портфель, по которому необходимо остановить получение новой информации.</param>
		void UnRegisterPortfolio(Portfolio portfolio);

		/// <summary>
		/// Поддерживает ли шлюз инструмент.
		/// </summary>
		/// <param name="security">Инструмент.</param>
		/// <returns>True, если шлюз поддерживает инструмент, иначе, false.</returns>
		bool IsSupport(Security security);
	}
}
